package MONITORING::APPL::HP::OM_OMi_COMPARE;

#################################################################
# $LastChangedDate: 2013-07-09 08:18:50 +0200 (Di, 09 Jul 2013) $
# $LastChangedRevision: 12 $
# $LastChangedBy: aswod_83@gmx.net $
#################################################################
use strict;
use base qw(moniCA::DBH::Oracle);
use XML::Simple;
use Data::Dumper;
use Sys::Hostname;
use Params::Validate qw(:all);
use Getopt::Long;

#-------------------------------------------------------------------------------
sub Run {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self      = shift;
    my $cnf       = $self->GetCNF();
    my $logger    = $self->GetLogger();
    my $statefile = $self->TmpDir() . '/' . $self->Plug() . '.xml';
    my %newstat;

    #-------------------------------------
    #	validation of default parameters
    #-------------------------------------
    $self->_validCNFdefaults( $cnf->{defaults} );

    #-------------------------------------
    #	validation of identifier parameters
    #-------------------------------------
    $self->_validCNFidentifierAll();

    #-------------------------------------
    #	pass through ALL tablespaces and compare fill size with treshold
    #-------------------------------------

    for ( sort keys %{ $self->{IdCfg} } ) {
        $self->{ID} = $_;
        $self->ConnectDB( $self->{IdCfg}->{$_}->{DBConnect} );
        $self->_getMessageIDs();
    }

    my $report = $self->{IdCfg}->{$_}->{'report'}
      || $self->{DefCfg}->{'report'};

    my @keys = keys( %{ $self->{identifier} } );
    my ( @union, @intersection, @difference );
    my %count = ();
    foreach my $element (
        @{ $self->{identifier}->{ @keys[0] }->{values} },
        @{ $self->{identifier}->{ @keys[1] }->{values} }
      )
    {
        $count{$element}++;
    }
    foreach my $element ( keys %count ) {
        push @union, $element;
        push @{ $count{$element} > 1 ? \@intersection : \@difference },
          $element;
    }

    foreach (@keys) {
        $self->{ID} = $_;
        Log::Log4perl::MDC->put( 'identifier', $self->{ID} );
        foreach my $a (@difference) {
            unless ( $a ~~ @{ $self->{identifier}->{$_}->{values} } ) {
                push @{ $self->{identifier}->{$_}->{missing} }, $a;
            }
        }
        $self->{identifier}->{$_}->{diff} =
          scalar( @{ $self->{identifier}->{$_}->{missing} } );
        $self->_validCNFrrd( $cnf->{rrd} ) && $self->_crReport()
          if ( $report =~ /on/i );

        $logger->error(
"tEvent: $self->{ID} $self->{identifier}->{$_}->{diff} message\(s\) missing"
        );

    }

    XMLout(
        \%{ $self->{identifier} },
        outputfile => $statefile,
        NoSort     => 0,
        XMLDecl    => 1
    );

}

#-------------------------------------------------------------------------------
sub _crReport {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------

    my $self   = shift;
    my $logger = $self->GetLogger();

    eval {

        require RRDs;

        ( my $rrdident = $self->{ID} ) =~ s/\W/_/g;

        my $rrdfile =
            $self->{RRDCfg}->{rrdfilepath} . '/'
          . $self->Plug() . '_'
          . $rrdident . '.rrd'
          if ( -d $self->{RRDCfg}->{rrdfilepath} ) || die($!);
        my $rrdimg =
            $self->{RRDCfg}->{rrdimgpath} . '/'
          . $self->Plug() . '_'
          . $rrdident . '.png'
          if ( -d $self->{RRDCfg}->{rrdimgpath} ) || die($!);

        if ( !-f $rrdfile ) {
            my @rrdc;
            push( @rrdc, "$rrdfile" );
            push( @rrdc, "--step=$self->{RRDCfg}->{step}" );
            if ( ref( $self->{RRDCfg}->{DS} ) eq "ARRAY" ) {
                for ( @{ $self->{RRDCfg}->{DS} } ) { push( @rrdc, $_ ); }
            }
            else {
                push( @rrdc, $self->{RRDCfg}->{DS} );
            }
            for ( @{ $self->{RRDCfg}->{RRA} } ) { push( @rrdc, $_ ); }

            RRDs::create(@rrdc);

            $logger->warn( "RRDs::create returns " . RRDs::error() )
              if ( RRDs::error() );
        }

        my @identlist;
        if ( ref( $self->{RRDCfg}->{DS} ) eq "ARRAY" ) {
            for ( @{ $self->{RRDCfg}->{DS} } ) {
                my @tmplist = split( /:/, $_ );
                push( @identlist, $tmplist[1] );
            }
        }
        else {
            my @tmplist = split( /:/, $self->{RRDCfg}->{DS} );
            push( @identlist, $tmplist[1] );
        }
        my $dslist = join( ":", @identlist );

        if ( -f $rrdfile ) {
            my @rrdu;
            my @dsvalue;
            for (@identlist) {
                push( @dsvalue, $self->{identifier}->{ $self->{ID} }->{$_} );
            }
            my $dsvalue = join( ":", @dsvalue );

            push( @rrdu, "$rrdfile" );
            push( @rrdu, "--template=$dslist" );
            push( @rrdu, "N:$dsvalue" );

            RRDs::update(@rrdu);

            $logger->warn( "RRDs::update returns " . RRDs::error() )
              if ( RRDs::error() );

            my @rrdg;
            $rrdfile =~ s/\:\//\\\:\//g if ( $^O eq 'MSWin32' );

            push( @rrdg, "$rrdimg" );
            push( @rrdg, "--title=$self->{RRDCfg}->{'title'}: $self->{ID}" );
            push( @rrdg, "--start=$self->{RRDCfg}->{'start'}" );
            push( @rrdg, "--end=$self->{RRDCfg}->{'end'}" );
            push( @rrdg, "--vertical-label=$self->{RRDCfg}->{'label'}" );
            push( @rrdg, "--imgformat=$self->{RRDCfg}->{'imgformat'}" );
            push( @rrdg, "--watermark=$self->{RRDCfg}->{'watermark'}" );
            push( @rrdg, "--width=$self->{RRDCfg}->{'width'}" );
            push( @rrdg, "--height=$self->{RRDCfg}->{'height'}" );

            foreach ( keys %{ $self->{RRDCfg}->{DEF} } ) {
                push( @rrdg,
                    "DEF:$_=$rrdfile:$_:$self->{RRDCfg}->{DEF}->{$_}->{CF}" );
                push( @rrdg,
"$self->{RRDCfg}->{DEF}->{$_}->{TYPE}:$_#$self->{RRDCfg}->{DEF}->{$_}->{COLOR}:$_ $self->{RRDCfg}->{DEF}->{$_}->{CF}"
                );
            }

            RRDs::graph(@rrdg);

            $logger->warn( "RRDs::graph returns " . RRDs::error() )
              if ( RRDs::error() );
        }
        1;
    } or $logger->debug( "Report incomplete: " . $@ );

}

#-------------------------------------------------------------------------------
sub _getMessageIDs {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self    = shift;
    my $stmt    = $self->{IdCfg}->{ $self->{ID} }->{DBConnect}->{stmt};
    my $ary_ref = $self->{DBH}->selectcol_arrayref($stmt);
    @{ $self->{identifier}->{ $self->{ID} }->{values} } = @$ary_ref;
    return $self;
}

#-------------------------------------------------------------------------------
sub _validCNFrrd {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 1 );
    $self->{RRDCfg} = validate(
        @_,
        {
            rrdfilepath => {
                type     => SCALAR,
                default  => $self->VarDir(),
                optional => 1,
                regex    => qr/^.+$/
            },
            rrdimgpath => {
                type     => SCALAR,
                default  => $self->VarDir() . "/images",
                optional => 1,
                regex    => qr/^.+$/
            },
            title  => { type => SCALAR },
            label  => { type => SCALAR },
            width  => { type => SCALAR, default => "400", regex => qr/\d\d\d/ },
            height => { type => SCALAR, default => "100", regex => qr/\d\d\d/ },
            start     => { type => SCALAR, default => "end-24hours" },
            end       => { type => SCALAR, default => "now" },
            imgformat => { type => SCALAR, regex   => qr/[PNG||GIF||PDF]/ },
            watermark =>
              { type => SCALAR, default => "powered by Andre Schmitt" },
            DS  => { type => ARRAYREF | SCALAR },
            RRA => { type => ARRAYREF | SCALAR }
        }
    );
    return $self;

}

#-------------------------------------------------------------------------------
sub _validCNFdefaults {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 0 );
    $self->{DefCfg} = validate(
        @_,
        {
            warnPct => { type => SCALAR, regex => qr/^\d+$/i },
            failPct => { type => SCALAR, regex => qr/^\d+$/i },
            report  => { type => SCALAR, regex => qr/^(on||off)$/i },
            trigger => { type => SCALAR, regex => qr/^.+$/ }
        }
    );
    return $self;
}

#-------------------------------------------------------------------------------
sub _validCNFidentifier {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;

    Params::Validate::validation_options( allow_extra => 1 );
    $self->{IdCfg}->{ $self->{ID} } = validate(
        @_,
        {
            warnPct => { type => SCALAR, regex => qr/^\d+$/i, optional => 1 },
            failPct => { type => SCALAR, regex => qr/^\d+$/i, optional => 1 },
            report =>
              { type => SCALAR, regex => qr/^(on||off)$/i, optional => 1 },
            trigger => { type => SCALAR, regex => qr/^.+$/, optional => 1 }
        }
    );
    return $self;
}

#-------------------------------------------------------------------------------
sub _validCNFidentifierAll {

#-------------------------------------------------------------------------------
# Description:
# Input Parms:
# Output Parms:
#-------------------------------------------------------------------------------
    my $self = shift;
    my $cnf  = $self->GetCNF();

    foreach ( keys %{ $cnf->{identifier} } ) {
        $self->{ID} = $_;
        $self->_validCNFidentifier( $cnf->{identifier}->{$_} );
    }
}
1;

__END__
 
=pod
 
=head1 NAME
 
 TABLESPACE_USAGE.pm - oracle tablespace monitor 
 
=head1 SYNOPSIS
  
=head1 DESCRIPTION
 
=head1 PREREQUISITES
 
C<Log::Log4perl>
C<XML::Simple>
 
=head1 CONFIGURATION SAMPLE
 
 Modul      MONITORING::DB::ORACLE::TABLESPACE_USAGE
 Logger     moniCA
 LogLevel   DEBUG
 BriefDesc  Check tablespace
 DetailDesc This moniCA plug checks free storage capacity \
			Reporting method collects usedPct,usedBytes,totalBytes
			
 #DOC: 
 #DOC: 
 #DOC: 

 <defaults>
         report  = on
         failPct = 90
         warnPct = 80
         trigger = 2
 </defaults>

 #DOC: 
 #DOC: 
 #DOC: 

 <DBConnect>
         ConnectString dbi:Oracle:SID=XE;HOST=localhost;port=1521
         dbuser        SYSTEM
         dbpw          manager
 </DBConnect>

 #DOC: 
 #DOC: 
 #DOC: 

 <identifier "USERS">
         failPct = 2 
         warnPct = 1 
 </identifier>

 #DOC: 
 #DOC: 
 #DOC: 

 <rrd>
         #rrdimgpath  =
         #rrdfilepath =
         step         = 300
         DS           = DS:usedPct:GAUGE:1200:0:100
         DS           =	DS:totalMBytes:GAUGE:1200:0:1000000
         DS           = DS:usedMBytes:GAUGE:1200:0:1000000
         RRA          = RRA:AVERAGE:0.5:1:800
         RRA          = RRA:AVERAGE:0.5:6:800
         RRA          = RRA:AVERAGE:0.5:24:800
         RRA          = RRA:AVERAGE:0.5:288:800
         title        = Tablespace
         label        = TablespaceUsage in % 
         width        = 400
         height       = 100
         start        = end-24hours
         end          = now
         watermark    =	powered by SAM
         imgformat    =	PNG
         <DEF "usedPct">
                 CF    = AVERAGE
 			     TYPE  = LINE2
 			     COLOR = FFC0CB
         </DEF>
 </rrd>

=cut
